import _ from "lodash";
import JournalModel from "../models/JournalModel";
import { JournalsEntity } from "../entities/JournalsEntity";
import MarkerModel from "../models/MarkerModel";

export default class JournalDao {
  static async add(journal: JournalsEntity): Promise<object> {
    try {
      const result = await JournalModel.create({
        ...journal,
      });

      return result.toJSON();
    } catch (err) {
      throw new Error(err.message || err.original.message);
    }
  }

  /**
   *
   * @param uid 用户 id
   * @param id 日志 id
   */
  static async del(uid: number, id: number): Promise<boolean> {
    try {
      const result = await JournalModel.destroy({
        where: {
          u_id: uid,
          id: id,
        },
      });

      return result > 0 ? true : false;
    } catch (err) {
      throw new Error(err.original.message);
    }
  }

  /**
   * 通过 用户id 和 marker id 查找 所有的日志的简略信息,
   * @param uid
   * @param mid
   * @returns
   */
  static async findByUidAndMidOmit(uid: number, mid: number) {
    try {
      const result = await JournalModel.findAll({
        order: [["createdAt", "DESC"]],
        attributes: {
          exclude: ["updatedAt", "title", "u_id", "createdAt"],
        },
        where: {
          u_id: uid,
          m_id: mid,
        },
      });

      return result;
    } catch (err) {
      throw new Error(err.original.message);
    }
  }

  /**
   * 查找用户公开的日志列表
   * @param uid
   * @param mid
   * @returns
   */
  static async findOpenJournalList(uid: number, mid: number) {
    try {
      const result = await JournalModel.findAll({
        order: [["createdAt", "DESC"]],
        attributes: {
          exclude: ["updatedAt", "createdAt"],
        },
        where: {
          u_id: uid,
          m_id: mid,
          is_open: true,
        },
      });

      return result;
    } catch (err) {
      throw new Error(err.original.message);
    }
  }

  /**
   * 查找用户公开的日志
   * @param uid
   * @param mid
   * @param id
   * @returns
   */
  static async findOneOpenJournal(
    uid: number,
    mid: number,
    id: number
  ): Promise<JournalsEntity | null> {
    try {
      const result = await JournalModel.findOne({
        order: [["createdAt", "DESC"]],
        attributes: {
          exclude: ["updatedAt", "u_id", "createdAt"],
        },
        include: {
          model: MarkerModel,
          required: true,
          attributes: ["name"],
        },
        where: {
          u_id: uid,
          m_id: mid,
          id,
          is_open: true,
        },
      });

      if (result) {
        return result.toJSON();
      } else {
        return null;
      }
    } catch (err) {
      throw new Error(err.original.message);
    }
  }

  static async findById(
    uid: number,
    id: number
  ): Promise<JournalsEntity | null> {
    try {
      const result = await JournalModel.findOne({
        include: {
          model: MarkerModel,
          required: true,
          attributes: ["name"],
        },
        where: {
          u_id: uid,
          id: id,
        },
      });

      if (result) {
        return result.toJSON();
      } else {
        return null;
      }
    } catch (err) {
      throw new Error(err.original.message);
    }
  }

  /**
   * 查找用户的所有日志
   * @param uid
   * @returns
   */
  static async findByPage(uid: number) {
    // UPDATE 更新为 分页查找
    try {
      const result = await JournalModel.findAll({
        where: {
          u_id: uid,
        },
      });

      return result;
    } catch (err) {
      throw new Error(err.original.message);
    }
  }

  static async modify(journal: JournalsEntity): Promise<boolean> {
    try {
      const result = await JournalModel.update(
        {
          ..._.omit(journal, "u_id", "id"),
        },
        {
          where: {
            u_id: journal.u_id,
            id: journal.id,
          },
        }
      );

      return result[0] > 0 ? true : false;
    } catch (err) {
      throw new Error(err.original.message);
    }
  }
}
